home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr47 / ucrasm27.zip / SOURCE.ZIP / INSCURM.ASM < prev    next >
Assembly Source File  |  1992-06-12  |  6KB  |  277 lines

  1.  
  2. ; Need to include "lists.a" in order to get list structure definition.
  3.  
  4.         include    lists.a
  5.         extrn    sl_malloc:far
  6.  
  7.  
  8. wp        equ    <word ptr>        ;I'm a lazy typist
  9.  
  10.  
  11. ; Special case to handle MASM 6.0 vs. all other assemblers:
  12. ; If not MASM 5.1 or MASM 6.0, set the version to 5.00:
  13.  
  14.         ifndef    @version
  15. @version    equ    500
  16.         endif
  17.  
  18.  
  19.  
  20. StdGrp        group    stdlib,stddata
  21. stddata        segment    para public 'sldata'
  22. stddata        ends
  23.  
  24. stdlib        segment    para public 'slcode'
  25.         assume    cs:stdgrp
  26.  
  27.  
  28. ; sl_InsertCurm-    DX:SI points at a block of data bytes.
  29. ;            ES:DI points at a list.
  30. ;            This routine allocates storage for a new node on the
  31. ;            heap, copies the data from DX:SI to the new node,
  32. ;            and then links in the new node to the list before
  33. ;            the current node.
  34. ;
  35. ;            Returns the carry set if memory allocation error
  36. ;            occurs.
  37. ;
  38. ; Randall Hyde  3/12/92
  39. ;
  40.  
  41.         public    sl_InsertCurm
  42. sl_InsertCurm    proc    far
  43.         pushf
  44.         push    ds
  45.         push    ax
  46.         push    bx
  47.         push    cx
  48.         push    es
  49.         push    di
  50.         cld
  51.  
  52.  
  53.  
  54.         if    @version ge 600
  55.  
  56. ; MASM 6.0 version goes here
  57.  
  58. ; First, allocate storage for the new node:
  59.  
  60.         mov    cx, es:[di].List.ListSize
  61.         push    cx            ;Save for later
  62.         add    cx, size NODE        ;Add in overhead
  63.         call    sl_malloc        ;Go get the memory
  64.         pop    cx            ;Get real length back.
  65.         jc    BadInsert        ;If malloc error
  66.         push    di            ;Save ptr to new NODE.
  67.  
  68. ; Compute offset to actual data area (skipping over list pointers, etc.)
  69.  
  70.         add    di, size Node
  71.  
  72.  
  73.         mov    ds, dx
  74.     rep    movsb                ;Copy the node's data.
  75.         pop    si            ;Get ptr to original node
  76.         mov    cx, es            ;Make ds:si point at node.
  77.         mov    ds, cx
  78.         pop    di            ;Get ptr to list var
  79.         pop    es
  80.         push    es
  81.         push    di
  82.  
  83. ; At this point, DS:SI points at the new node on the heap and ES:DI points
  84. ; at the list variable.
  85.  
  86. ; See if the the list is empty:
  87.  
  88.         cmp    wp es:[di].List.Head+2, 0
  89.         jne    ListHasNodes
  90.  
  91. ; If this is an empty list (list is empty if HEAD is NIL), then build the
  92. ; list from this single node.
  93.  
  94.         mov    wp es:[di].List.Tail, si
  95.         mov     wp es:[di].List.Head, si
  96.         mov    wp es:[di].List.CurrentNode, si
  97.         mov    wp es:[di].List.Tail+2, ds
  98.         mov    wp es:[di].List.Head+2, ds
  99.         mov    wp es:[di].List.CurrentNode+2, ds
  100.  
  101. ; Set the link fields of this new node to NIL.
  102.  
  103.         mov    wp [si].Node.Next, 0
  104.         mov    wp [si].Node.Prev, 0
  105.         mov    wp [si].Node.Next+2, 0
  106.         mov    wp [si].Node.Prev+2, 0
  107.  
  108.         pop    di
  109.         pop    es
  110.         jmp    GoodInsert
  111.  
  112.  
  113. ;If there were items in the list, perform the insert down here.
  114.  
  115. ListHasNodes:    les    di, es:[di].List.CurrentNode    ;Get ptr to item
  116.         mov    ax, wp es:[di].Node.Prev    ;Get ptr to prev
  117.         mov    bx, wp es:[di].Node.Prev+2    ; node and save.
  118.  
  119. ; Use the address of CurrentNode as the next ptr for the new node.
  120.  
  121.         mov    wp ds:[si].Node.Next, di     ;Patch in link
  122.         mov    wp ds:[si].Node.Next+2, es
  123.  
  124. ; Okay, store the new node's address into the PREV field of the current node
  125.  
  126.         mov    wp es:[di].Node.Prev, si    ;Patch in fwd ptr
  127.         mov    wp es:[di].Node.Prev+2, ds
  128.  
  129. ; Set the PREV field of the new node to the original previous node.
  130.  
  131.         mov    wp ds:[si].Node.Prev, ax
  132.         mov    wp ds:[si].Node.Prev+2, bx
  133.  
  134. ; Set the Next field of the original previous node to point at the new
  135. ; node:
  136.  
  137.         mov    es, bx
  138.         mov    di, ax
  139.         mov    wp es:[di].Node.Next, si
  140.         mov    wp es:[di].Node.Next+2, ds
  141.  
  142. ; Set the CurrentNode ptr to the new node
  143.  
  144.         pop    di            ;Retrive ptr to list var.
  145.         pop    es
  146.         mov    wp es:[di].List.CurrentNode, si
  147.         mov    wp es:[di].List.CurrentNode+2, ds
  148.  
  149.  
  150.  
  151.  
  152.  
  153.         else
  154.  
  155. ; All other assemblers come down here:
  156.  
  157. ; First, allocate storage for the new node:
  158.  
  159.         mov    cx, es:[di].ListSize
  160.         push    cx            ;Save for later
  161.         add    cx, size NODE        ;Add in overhead
  162.         call    sl_malloc         ;Go get the memory
  163.         pop    cx            ;Get real length back.
  164.         jnc    GoodIns
  165.         jmp    BadInsert        ;If malloc error
  166.  
  167. GoodIns:    push    di            ;Save ptr to new NODE.
  168.  
  169. ; Compute offset to actual data area (skipping over list pointers, etc.)
  170.  
  171.         add    di, size Node
  172.  
  173.  
  174.         mov    ds, dx
  175.     rep    movsb                ;Copy the node's data.
  176.         pop    si            ;Get ptr to original node
  177.         mov    cx, es            ;Make ds:si point at node.
  178.         mov    ds, cx
  179.         pop    di            ;Get ptr to list var
  180.         pop    es
  181.         push    es
  182.         push    di
  183.  
  184. ; At this point, DS:SI points at the new node on the heap and ES:DI points
  185. ; at the list variable.
  186.  
  187. ; See if the the list is empty:
  188.  
  189.         cmp    wp es:[di].Head+2, 0
  190.         jne    ListHasNodes
  191.  
  192. ; If this is an empty list (list is empty if HEAD is NIL), then build the
  193. ; list from this single node.
  194.  
  195.         mov    wp es:[di].Tail, si
  196.         mov     wp es:[di].Head, si
  197.         mov    wp es:[di].CurrentNode, si
  198.         mov    wp es:[di].Tail+2, ds
  199.         mov    wp es:[di].Head+2, ds
  200.         mov    wp es:[di].CurrentNode+2, ds
  201.  
  202. ; Set the link fields of this new node to NIL.
  203.  
  204.         mov    wp [si].Next, 0
  205.         mov    wp [si].Prev, 0
  206.         mov    wp [si].Next+2, 0
  207.         mov    wp [si].Prev+2, 0
  208.  
  209.         pop    di
  210.         pop    es
  211.         jmp    GoodInsert
  212.  
  213.  
  214. ;If there were items in the list, perform the insert down here.
  215.  
  216. ListHasNodes:    les    di, es:[di].CurrentNode    ;Get ptr to item
  217.         mov    ax, word ptr es:[di].Prev    ;Get ptr to prev
  218.         mov    bx, word ptr es:[di].Prev+2    ; node and save.
  219.  
  220. ; Use the address of CurrentNode as the next ptr for the new node.
  221.  
  222.         mov    wp ds:[si].Next, di     ;Patch in link
  223.         mov    wp ds:[si].Next+2, es
  224.  
  225. ; Okay, store the new node's address into the PREV field of the current node
  226.  
  227.         mov    wp es:[di].Prev, si    ;Patch in fwd ptr
  228.         mov    wp es:[di].Prev+2, ds
  229.  
  230. ; Set the PREV field of the new node to the original previous node.
  231.  
  232.         mov    wp ds:[si].Prev, ax
  233.         mov    wp ds:[si].Prev+2, bx
  234.  
  235. ; Set the Next field of the original previous node to point at the new
  236. ; node:
  237.  
  238.         mov    es, bx
  239.         mov    di, ax
  240.         mov    wp es:[di].Next, si
  241.         mov    wp es:[di].Next+2, ds
  242.  
  243. ; Set the CurrentNode ptr to the new node
  244.  
  245.         pop    di            ;Retrive ptr to list var.
  246.         pop    es
  247.         mov    wp es:[di].CurrentNode, si
  248.         mov    wp es:[di].CurrentNode+2, ds
  249.  
  250.  
  251.         endif
  252.  
  253. ; DANGER WILL ROBINSON! Multiple exit points.  Be wary of these if you
  254. ; change the way things are pushed on the stack.
  255.  
  256. GoodInsert:    pop    cx
  257.         pop    bx
  258.         pop    ax
  259.         pop    ds
  260.         popf
  261.         clc
  262.         ret
  263.  
  264. BadInsert:    pop    di
  265.         pop    es
  266.         pop    cx
  267.         pop    bx
  268.         pop    ax
  269.         pop    ds
  270.         popf
  271.         stc
  272.         ret
  273. sl_InsertCurm    endp
  274.  
  275. stdlib        ends
  276.         end
  277.